_require local "../../basis.smi"
_require local "./base.sig"
_require local "./stream.smi"
_require "./lrtable.smi"

(* 2012-9-24: ohori
  This is the top-level library structure.
  This is changed to a functor that takes
    type pos
    type svalue
    type arg

   changed 'arg => arg
   eliminated type parameters in token
   and changed accordingly:
     (('a,'b) token => token
     'a => Token.svalue
     'b => Token.pos
*)

functor LrParserFun (A : sig type arg type pos type svalue end) =
struct
  type arg = A.arg
  type pos = A.pos
  type svalue = A.svalue
  structure LrTable = LrTable
  structure Token =
  struct
    type svalue = A.svalue
    type pos = A.pos
    structure LrTable = LrTable
    datatype token = TOKEN of LrTable.term * (svalue * pos * pos)
    val sameToken : token * token -> bool
  end
  type actions = 
       int * pos * (LrTable.state * (svalue * pos * pos)) list * arg ->
       LrTable.nonterm * (svalue * pos * pos) *
       ((LrTable.state *(svalue * pos * pos)) list)
  structure Stream = 
  struct
    type tok = Token.token
    type stream (= ref)
    val streamify : (unit -> tok) -> stream
    val cons : tok * stream -> stream
    val get : stream -> tok * stream
  end
  exception ParseError
  val parse
      : {table : LrTable.table,
         lexer : Stream.stream,
         arg: arg,
         saction : actions,
         void : Token.svalue,
         ec : {is_keyword : LrTable.term -> bool,
               noShift : LrTable.term -> bool,
               preferred_change : (LrTable.term list * LrTable.term list)
                                  list,
               errtermvalue : LrTable.term -> Token.svalue,
               showTerminal : LrTable.term -> string,
               terms: LrTable.term list,
               error : string * Token.pos * Token.pos -> unit},
         lookahead : int} -> Token.svalue * Stream.stream
end
